
package com.yadong.numberguess;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.yadong.numberguess.Game.GameType;
import com.yadong.numberguess.Game.Result;

public class MainActivity extends Activity implements OnClickListener {
    private static final int NUMBER_IDS[] = new int[] {
            R.id.one, R.id.two, R.id.three, R.id.four
            , R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.zero, R.id.x, R.id.y,
            R.id.z
    };

    private TextView mShowing;
    private ListView mListView;
    private List<View> mCheckedList;
    private Button mCommitBtn;
    private Button mBackBtn;
    private Button mNewGame;
    private Button mModeBtn;
    private Game mGame;
    private ResultListAdapter mAdapter;
    private Dialog mDialog;
    private long mStartTime = -1;
    private GameType mCurrentGameType = GameType.SIMPLE;
    private DataSaver mDataSaver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDataSaver = new DataSaver(this);
        mCurrentGameType = GameType.values()[mDataSaver.getGameMode()];
        mGame = new Game(mCurrentGameType);
        mCheckedList = new ArrayList<View>();
        mShowing = (TextView) findViewById(R.id.input);
        mListView = (ListView) findViewById(R.id.list);
        mAdapter = new ResultListAdapter();
        mListView.setAdapter(mAdapter);
        mCommitBtn = (Button) findViewById(R.id.btn_commit);
        mBackBtn = (Button) findViewById(R.id.btn_back);
        mNewGame = (Button) findViewById(R.id.new_game);
        mCommitBtn.setOnClickListener(this);
        mBackBtn.setOnClickListener(this);
        mNewGame.setOnClickListener(this);
        initGameModeButton();
        initAllButtons();
        startNewGame();
    }
    private void initGameModeButton() {
        mModeBtn = (Button) findViewById(R.id.btn_mode);
        mModeBtn.setOnClickListener(this);
        setGameModeText(mCurrentGameType);
    }

    private void setGameModeText(GameType gameType) {
        mModeBtn.setText(gameType == GameType.SIMPLE ? "简单" : "困难");
    }

    private void setGameType(GameType gameType) {
        this.mCurrentGameType = gameType;
        mGame = new Game(mCurrentGameType);
        setGameModeText(mCurrentGameType);
        initAllButtons();
        startNewGame();
        mDataSaver.setGameMode(gameType.ordinal());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.action_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.game_rules:{
                Intent intent = new Intent(MainActivity.this, TextActivity.class);
                intent.putExtra(TextActivity.EXTRA_CONTENT, getString(R.string.game_rule));
                startActivity(intent);
                return true;
            }
            case R.id.game_record:{
                Intent intent = new Intent(MainActivity.this, TextActivity.class);
                String record = String.format(getString(R.string.game_reocrd_format),
                        mDataSaver.getLessTime(GameType.SIMPLE)/1000,
                        mDataSaver.getLessStep(GameType.SIMPLE),
                        mDataSaver.getLessTime(GameType.HARD)/1000,
                        mDataSaver.getLessStep(GameType.HARD));
                intent.putExtra(TextActivity.EXTRA_CONTENT, record);
                startActivity(intent);
                return true;
            }
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
            startNewGame();
        }
    }

    private void initAllButtons() {
        for (int i = 0; i < NUMBER_IDS.length; i++) {
            View view = findViewById(NUMBER_IDS[i]);
            view.setOnClickListener(this);
        }
        if (mCurrentGameType == GameType.HARD) {
            findViewById(R.id.x).setEnabled(true);
            findViewById(R.id.y).setEnabled(true);
            findViewById(R.id.z).setEnabled(true);
        } else {
            findViewById(R.id.x).setEnabled(false);
            findViewById(R.id.y).setEnabled(false);
            findViewById(R.id.z).setEnabled(false);
        }
    }

    private void onNumberButtonClick(View view) {
        if (mCheckedList.size() >= mGame.getLength()) {
            return;
        }

        String clickedNumber = null;
        int viewId = view.getId();
        if (viewId == R.id.zero) {
            clickedNumber = "0";
        } else if (viewId == R.id.x) {
            clickedNumber = "x";
        } else if (viewId == R.id.y) {
            clickedNumber = "y";
        } else if (viewId == R.id.z) {
            clickedNumber = "z";
        } else {
            for (int i = 0; i < NUMBER_IDS.length; i++) {
                if (NUMBER_IDS[i] == viewId) {
                    clickedNumber = (i + 1) + "";
                    break;
                }
            }
        }
        mShowing.append(clickedNumber);
        disableButton(view);
    }

    private void disableButton(View view) {
        view.setEnabled(false);
        mCheckedList.add(view);
        chaneBtnState();
    }

    private void chaneBtnState() {
        mCommitBtn.setEnabled(mCheckedList.size() == mGame.getLength());
        mBackBtn.setEnabled(mCheckedList.size() > 0);
    }

    private void onBackButtonPress() {
        if (mCheckedList.size() > 0) {
            View view = mCheckedList.remove(mCheckedList.size() - 1);
            view.setEnabled(true);
            String text = mShowing.getText().toString();
            mShowing.setText(text.subSequence(0, text.length() - 1));
        }
        chaneBtnState();
    }

    private void clearInput() {
        for (int id : NUMBER_IDS) {
            findViewById(id).setEnabled(true);
        }
        initAllButtons();
        mCheckedList.clear();
        mShowing.setText("");
        chaneBtnState();
    }

    private void startNewGame() {
        clearInput();
        mGame.reset();
        mAdapter.clearResult();
    }

    private class ResultListAdapter extends BaseAdapter {
        List<Result> mResults = new ArrayList<Result>();

        public void addResult(Result result) {
            mResults.add(result);
            notifyDataSetChanged();
        }

        public void clearResult() {
            mResults.clear();
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return mResults.size();
        }

        @Override
        public Object getItem(int index) {
            return mResults.get(index);
        }

        @Override
        public long getItemId(int index) {
            return 0;
        }

        @Override
        public View getView(int index, View view, ViewGroup viewGroup) {
            if (view == null) {
                view = getLayoutInflater()
                        .inflate(R.layout.list_item, viewGroup, false);
            }
            Result result = mResults.get(index);
            ((TextView) view.findViewById(R.id.text1)).setText(result.time + "");
            ((TextView) view.findViewById(R.id.text2)).setText(result.input);
            ((TextView) view.findViewById(R.id.text3)).setText(result.reminder);
            return view;
        }
    }

    //disable all button except new game button 
    private void showResult() {
        ViewGroup container = ((ViewGroup)findViewById(R.id.container));
        for(int i = 0; i < container.getChildCount(); i++) {
            View view = container.getChildAt(i);
            view.setEnabled(false);
        }
        mNewGame.setEnabled(true);
        mModeBtn.setEnabled(true);
    }

    private void createAndShowSuccess(long time,final int step,
            boolean lessTime, boolean lessStep) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("游戏结束")
            .setMessage("恭喜你猜对了, 结果是:" + mGame.getRealNumber() + "\n"
                    + "共用时间:" + (System.currentTimeMillis() - mStartTime)/1000 + "s\n"
                    + "共使用:" + step + "步\n"
                    + (lessTime ? "创造了时间最短记录!!\n" : "")
                    + (lessStep ? "创造了步数最少记录!!" : ""))
            .setPositiveButton("再来一局", new AlertDialog.OnClickListener() {
            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                startNewGame();
            }
        }).setNegativeButton("关闭", new AlertDialog.OnClickListener() {
            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                if (step == 6/*just for fun*/) {
                    startNewGame();
                    Intent intent = new Intent(MainActivity.this, EasterEggsActivity.class);
                    startActivity(intent);
                } else {
                    showResult();
                }
            }
        });
        mDialog = builder.create();
        mDialog.setCancelable(false);
        mDialog.show();
    }

    @Override
    public void onClick(View view) {
        int viewId = view.getId();
        switch (viewId) {
            case R.id.btn_back:
                onBackButtonPress();
                break;
            case R.id.btn_commit:
                Result result = mGame.guess(mShowing.getText().toString());
                mAdapter.addResult(result);
                mListView.smoothScrollToPosition(mAdapter.getCount() - 1);
                clearInput();
                // number is guessed
                if (result.success) {
                    long useTime = System.currentTimeMillis() - mStartTime;
                    int step = result.time;
                    long lessTime = mDataSaver.getLessTime(mCurrentGameType);
                    int lessStep = mDataSaver.getLessStep(mCurrentGameType);
                    boolean isLessTime = false;
                    boolean isLessStep = false;
                    if (lessTime == -1 || lessTime > useTime) {
                        mDataSaver.setLessTime(mCurrentGameType, useTime);
                        isLessTime = true;
                    }
                    if (lessStep == -1 || lessStep > step) {
                        mDataSaver.setLessStep(mCurrentGameType, step);
                        isLessStep = true;
                    }
                    createAndShowSuccess(useTime, step, isLessTime, isLessStep);
                    //clear time
                    mStartTime = -1;
                }
                // record time
                if (mStartTime == -1) {
                    mStartTime = System.currentTimeMillis();
                }
                break;
            case R.id.new_game:
                startNewGame();
                break;
            case R.id.btn_mode:
                if (mCurrentGameType == GameType.SIMPLE) {
                    setGameType(GameType.HARD);
                } else {
                    setGameType(GameType.SIMPLE);
                }
                break;
            default:
                onNumberButtonClick(view);
                break;
        }
    }
}
